package com.ymx.darling.dialect;

import com.ymx.darling.exception.ExceptionFactory;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;

/**
 * 方言管理器
 * @author 爱Java的小于
 */
public class DialectManager {
    private final static Map<String, Dialect> defaultDialects;
    private static Dialect currentDialect;
    static {
        defaultDialects = new HashMap<>();
        defaultDialects.put("mysql", new MySqlDialect());
        defaultDialects.put("oracle", new OracleDialect());
        defaultDialects.put("sql server", new SqlServerDialect());
        defaultDialects.put("postgresql", new PostgresDialect());
        defaultDialects.put("db2", new DB2Dialect());
        defaultDialects.put("kingbase", new KingbaseDialect());
        defaultDialects.put("dm", new DmDialect());
        defaultDialects.put("sqlite", new SQLiteDialect());
    }

    public static Dialect getDialect(){
        return currentDialect;
    }

    /**
     * 设置新的数据库方言
     * @param dialect 方言
     */
    public static void setDialect(Dialect dialect) {
        DialectManager.currentDialect = dialect;
    }

    /**
     * 返回数据源方言如果为空那么根据datasource获取方言并返回
     * @param dataSource datasource
     * @return dialect
     */
    public static Dialect getDialectIfAbsent(DataSource dataSource) {
        if (getDialect() == null) {
            setDialect(getDialectByDataSource(dataSource));
        }
        return getDialect();
    }


    /**
     * 返回指定数据源的方言
     * @param dataSource 数据源
     * @return Dialect
     */
    private static Dialect getDialectByDataSource(DataSource dataSource) {
        try {
            Connection connection = dataSource.getConnection();
            DatabaseMetaData metaData = connection.getMetaData();
            String databaseProductName = metaData.getDatabaseProductName().toLowerCase();
            return defaultDialects.get(databaseProductName);
        } catch (SQLException e) {
            String errMsg = e.getClass().getName()+":"+e.getMessage();
            throw ExceptionFactory.wrapException("尝试获取数据源"+dataSource+"的方言时发生异常.原因:"+errMsg, e);
        }
    }
}
